﻿using Com.Lancetinc.Evs.Config;
using Com.Lancetinc.Evs.Data;
using Com.Lancetinc.Evs.Helpers;
using Com.Lancetinc.Evs.Reports;
using Com.Lancetinc.Evs.Services;
using Com.Lancetinc.Evs.ViewModels;
using Com.Lancetinc.Evs.Windows;
using NLog;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;

namespace Com.Lancetinc.Evs.Controls
{
    /// <summary>
    /// 报告
    /// </summary>
    public partial class ReportTemplateUserControl
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        public ReportViewModel ViewModel { get; private set; }

        public ReportTemplateUsage Usage { get; private set; } = ReportTemplateUsage.Preview;

        public event EventHandler ReportPrinted;

        public ReportTemplateUserControl()
        {
            InitializeComponent();
            this.Loaded += ReportTemplateUserControl_Loaded;
        }

        public void Setup(ReportViewModel rptVm, ReportTemplateUsage usage = ReportTemplateUsage.Preview)
        {
            this.Usage = usage;
            this.ViewModel = rptVm;
            this.DataContext = ViewModel;
            if (usage == ReportTemplateUsage.Preview)
            {
                LblDiagnosis.Visibility = Visibility.Visible;
            }
            else if (usage == ReportTemplateUsage.Edit)
            {
                TxtDiagnosis.Visibility = Visibility.Visible;

                GongSolutions.Wpf.DragDrop.DragDrop.SetIsDragSource(CtrlImages, true);
                GongSolutions.Wpf.DragDrop.DragDrop.SetIsDropTarget(CtrlImages, true);
            }
        }

        private void ReportTemplateUserControl_Loaded(object sender, RoutedEventArgs e)
        {
            OnLoaded();
        }

        private bool _loaded = false;
        public void OnLoaded()
        {
            if (_loaded)
                return;

            _loaded = true;
            ReLoadBanner();
        }

        public void ReLoadBanner()
        {
            GridBanner.Children.Clear();

            var config = AppConfigs.ReportConfig;
            if (config.UseBanner)
            {
                var bannerSource = ReportHelper.LoadBannerImage();
                if (bannerSource != null)
                {
                    var img = new Image
                    {
                        Source = bannerSource,
                        Stretch = Stretch.Fill
                    };
                    GridBanner.Children.Add(img);
                    return;
                }
                return;
            }

            var reportTitle = ReportHelper.GetReportTitle();
            if (string.IsNullOrEmpty(reportTitle))
                return;

            var lblReportTitle = new TextBlock
            {
                Text = reportTitle,
                FontSize = 36,
                HorizontalAlignment = HorizontalAlignment.Center,
                TextAlignment = TextAlignment.Center,
                Foreground = Brushes.Black,
                Margin = new Thickness(10, 0, 10, 0),
                TextWrapping = TextWrapping.Wrap
            };

            var titlePanel = new StackPanel
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
            };
            titlePanel.Children.Add(lblReportTitle);

            var reportSubTitle = ReportHelper.GetReportSubTitle();
            if (!string.IsNullOrWhiteSpace(reportSubTitle))
            {
                var lblReportSubTitle = new TextBlock
                {
                    Text = reportSubTitle,
                    FontSize = 32,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    TextAlignment = TextAlignment.Center,
                    Foreground = Brushes.Black,
                    Margin = new Thickness(10, 0, 10, 0),
                    TextWrapping = TextWrapping.Wrap
                };
                titlePanel.Children.Add(lblReportSubTitle);
            }

            GridBanner.Children.Add(titlePanel);
        }

        public void InsertImage(string imgFilePath)
        {
            if (Usage == ReportTemplateUsage.Preview)
                return;

            if (ViewModel.Images.Contains(imgFilePath))
                return;

            if (ViewModel.Images.Count >= AppConsts.ReportMaxImages)
            {
                // 最多插入6张截图，请选择已插入图片删除一张后再进行插入图片操作
                var msg = I18nHelper.Default.GetMessageWithArgs("MaxIllustrationExceedA", AppConsts.ReportMaxImages);
                MessageHelper.Show(msg);
                return;
            }

            ViewModel.Images.Add(imgFilePath);
            ViewModel.SaveReportImages();
        }

        private bool _firstInsert = true;
        public void InsertTerm(string term)
        {
            if (string.IsNullOrEmpty(term))
                return;

            int caretIndex = TxtDiagnosis.CaretIndex;
            if (_firstInsert && caretIndex == 0)
            {
                caretIndex = TxtDiagnosis.Text.Length;
            }

            term += Environment.NewLine;
            _firstInsert = false;
            TxtDiagnosis.Text = TxtDiagnosis.Text.Insert(caretIndex, term);
            TxtDiagnosis.CaretIndex = caretIndex + term.Length;
            WpfHelper.ExecLater(() =>
            {
                TxtDiagnosis.Focus();
            }, 100);
        }

        public async Task<bool> Print()
        {
            var pd = new PrintDialog();
            //pd.PrintQueue = new PrintQueue(new PrintServer(), "Microsoft XPS Document Writer");

            if (pd.ShowDialog() != true)
                return false;
            var printerName = pd.PrintQueue.Name;
            var printTime = DateTime.Now;
            var title = I18nHelper.Default.GetMessage("Print");
            var msg = I18nHelper.Default.GetMessageWithArgs("Printing", printerName); // 正在打印到{0}...
            using var pc = await WaitBoxHelper.WaitBox.ShowAsync(title, msg, false, false);

            var doc = CreateDocument();
            pd.PrintDocument(doc.DocumentPaginator, ReportHelper.GetReportTitle());

            pc.Message = I18nHelper.Default.GetMessage("PrintingPdf"); //正在打印到PDF...
            await Task.Delay(33);

            var reportDir = ExperManager.Default.GetReportDir(ViewModel.ExperVm.SeqNo);
            DirUtil.EnsureDirectoryExists(reportDir);
            var pdfFileName = Path.Combine(reportDir, printTime.ToString("yyyyMMdd_HHmmss") + ".pdf");
            PrintToPdf(pdfFileName);

            var expVm = ViewModel.ExperVm;
            expVm.PrintCount++;
            expVm.Exper.LastPrintTime = printTime.FormatForDbUpdate();
            AppRepositories.Exper.UpdatePrintCount(expVm.SeqNo, expVm.PrintCount, printTime);

            ReportPrinted?.Invoke(this, EventArgs.Empty);
            return true;
        }

        public void PrintToXps(string xpsFile)
        {
            var ctrl = new ReportTemplateUserControl();
            ctrl.Setup(this.ViewModel);
            ctrl.OnLoaded();
            var pageSize = new Size(this.ActualWidth, this.ActualHeight);
            ReportHelper.PrintToXps(ctrl, pageSize, xpsFile);
        }

        public void PrintToPdf(string pdfFile)
        {
            var pageSize = new Size(this.ActualWidth, this.ActualHeight);
            ReportHelper.PrintToPdf(this, pageSize, pdfFile);
        }

        public FixedDocument CreateDocument()
        {
            var ctrl = new ReportTemplateUserControl();
            ctrl.Setup(this.ViewModel);
            ctrl.OnLoaded();
            return ReportHelper.CreateDocument(ctrl);
        }

        private void GridImg_OnMouseEnter(object sender, MouseEventArgs e)
        {
            var grid = sender as Grid;
            if (Usage == ReportTemplateUsage.Preview)
            {
                grid.MouseEnter -= GridImg_OnMouseEnter;
                return;
            }

            var btn = grid.Children.OfType<Button>().FirstOrDefault();
            if (btn == null) return;
            btn.Visibility = Visibility.Visible;
        }

        private void GridImg_OnMouseLeave(object sender, MouseEventArgs e)
        {
            var grid = sender as Grid;
            if (Usage == ReportTemplateUsage.Preview)
            {
                grid.MouseLeave -= GridImg_OnMouseLeave;
                return;
            }

            var btn = grid.Children.OfType<Button>().FirstOrDefault();
            if (btn == null) return;
            btn.Visibility = Visibility.Collapsed;
        }
    }
}